// =================================================================
// File: rmdir.cpp
// Desc: Contains function for removing a directory
// =================================================================

// =================================================================
// INCLUDES
// =================================================================

#include <string>
#include "FSManager.h"
#include "commands.h"
#include "File.h"
#include "Directory.h"
#include "Inode.h"
#include "IndirectBlock.h"
#include "config.h"

using namespace std;

// =================================================================
// FUNCTIONS
// =================================================================

// =================================================================
// Name: rmdir
// Desc: Removes the specified directory if it is empty
// Args: string dir_name - the directory to remove
//       FSManager* fsm - pointer to active FSManager object
// =================================================================

void rmdir(string dir_name, FSManager *fsm){

  int inode_index;
  Inode *node;
  Directory *dir;
  Directory *parent_dir;

  // cout << "current_dir: " << fsm->GetCurrentDirectory() << endl;
  
  // if (dir_name[dir_name.length()-1] != '/')
  //  dir_name += '/';
  
  dir = fsm->ReadDirectory(dir_name);

  if(dir->GetInodeIndex() == fsm->GetRootDirectory()->GetInodeIndex() || dir->GetInodeIndex() == fsm->GetCurrentDirectory()->GetInodeIndex()){
    cerr << "CAN NOT REMOVE ROOT OR CURRENT DIRECTORY\n";
    return;
  }

  size_t found = dir_name.find_last_of("/");
  if (found == string::npos) {
    parent_dir = fsm->GetCurrentDirectory();
  } else {
    parent_dir = fsm->ReadDirectory(dir_name.substr(0, found));
  }

  if(dir_name[dir_name.length()-1] != '/'){
    dir_name += '/';
  }

  //parent_dir = fsm->ReadDirectory((dir_name + "../"));

  inode_index = dir->GetInodeIndex();

  node = fsm->ReadInode(inode_index);

  if(dir->GetEntries().size() != 2){
    cerr << "CAN NOT REMOVE DIRECTORY " << dir_name << " CONTAINS FILES\n";
    return;
  }
  node->SetNumLinks(node->GetNumLinks()-1);
  if (node->GetNumLinks() <= 0)
    delete_blocks(node,fsm);

  dir_name.erase(dir_name.length()-1);
  found = dir_name.find_last_of("/");

  string name = (dir_name.substr(found+1) + "/");


  // cout << "Attempting to remove entry: " << name << endl;
  // cout << "Parent Inode: " << parent_dir->GetInodeIndex() << endl;

  parent_dir->RemoveEntry(name);
  fsm->WriteDirectory(parent_dir);

  // Update in-memory current and root directory structures
  if(parent_dir->GetInodeIndex() == fsm->GetRootDirectory()->GetInodeIndex()){
    //Directory *root_dir = fsm->GetRootDirectory();
    //delete root_dir;

    // Update current if current and root directory are equal
    if (fsm->GetRootDirectory() == fsm->GetCurrentDirectory())
      fsm->SetCurrentDirectory(parent_dir);
    fsm->SetRootDirectory(parent_dir);
  }
  else if(parent_dir->GetInodeIndex() == fsm->GetCurrentDirectory()->GetInodeIndex()){
    
    Directory *current_dir = fsm->GetCurrentDirectory();
    if (current_dir != parent_dir) 
      delete current_dir;
    fsm->SetCurrentDirectory(parent_dir);
  }

  // If parent is neither root or current, safe to delete
  else
  {
    delete parent_dir;
  }

  if(node->GetNumLinks() == 0){
    fsm->GetSB()->AddFreeInode(inode_index);
    delete node;
  }
  delete dir;

  cout << "Directory " << dir_name << " deleted" << endl;
}
